#ifndef EDITOR_H
#define EDITOR_H

#include <set>
#include <list>

#include "../BSP.h"
#include "../signalslot.h"

#include "../GLMesh.h"
#include "../Entities.h"

class Camera;
class MyBaseElement;

class BuilderBrush {

protected:
	float bbox_min_[3];
	float bbox_max_[3];
	float center_[3];

	float lines_[72];
	float bold_points_[ 8 * 3 ];
	float points_[ 12 * 3 ];

	int move_point_;

	bool selected_;

	float color_[3];

public:
	BuilderBrush();
	~BuilderBrush(){
	}

	inline const float* bbox_min(){ return bbox_min_; }
	inline const float* bbox_max(){ return bbox_max_; }

	void set_selected(bool b){ selected_ = b; }

	void Move(float vec[3]);
	bool Check(float x, float y, Camera& cam, MyBaseElement& element);
	bool MovePoints(float dx, float dy, Camera& cam, MyBaseElement& element);
	void UpdateLines();

	void Draw();

};

//class Brush;

enum { SELECT_MODE, EDIT_MODE, TEX_MODE };

class SelectionFrame : public BuilderBrush {

	
	std::set<Brush*> selection_;
	std::set<Poly*> selected_faces_;
	std::set<MovableObject*> selected_objects_;
	std::set<BaseEntity*> selected_entities_;
	int mode_;

public:
	SelectionFrame();
	~SelectionFrame();

	std::set<Brush*> selection(){return selection_;}
	std::set<Poly*> selected_faces(){return selected_faces_;}
	std::set<MovableObject*> selected_objects(){return selected_objects_;}
	std::set<BaseEntity*> selected_entities(){return selected_entities_;}

	int mode(){ return mode_; }

	bool edit_mode(){ return (mode_ == EDIT_MODE); }

	void set_mode(int mode) {

		if(mode_ == EDIT_MODE && mode != EDIT_MODE)
		{
			for(auto brush = selection_.begin(); brush != selection_.end(); brush++)
			{
				(*brush)->RebuildFromPolys();
			}
			Update();
		}
		if(mode_ == TEX_MODE && mode != TEX_MODE)
		{
			for(auto p_poly_it = selected_faces_.begin(); p_poly_it != selected_faces_.end(); p_poly_it++)
			{
				(*p_poly_it)->legal = true;
			}
			selected_faces_.clear();
		}

		mode_ = mode;
	}

	/*void set_edit_mode(bool mode){
		edit_mode_ = mode; 
		if(!edit_mode_)
		{
			for(auto brush = selection_.begin(); brush != selection_.end(); brush++)
			{
				//(*brush)->UpdateBbox();
				(*brush)->RebuildFromPolys();
			}
			Update();
		}
	}*/

	void Add(Brush*);
	void Add(MovableObject*);
	void Add(BaseEntity*);
	void Add(Poly*);
	void Remove(Brush*);
	void Clear();
	void Update();
	void Update(Brush* new_brush);
	bool Empty();

	void Draw();
	bool Check(float x, float y, Camera& cam, MyBaseElement& element);
	bool CheckBrush(float x, float y, Camera& cam, MyBaseElement& element);
	bool CheckMesh(float x, float y, Camera& cam, MyBaseElement& element);
	bool CheckEntity(float x, float y, Camera& cam, MyBaseElement& element);
	void DeleteSelection();
	void CopySelection();
	bool MovePoints(float dx, float dy, Camera& cam, MyBaseElement& element);
	void Rotate(const float* axis, const float angle);
	void RotateFromView(const float angle, Camera& cam);
	void SetFreezeTexture(bool b);
	void SetTexrure(std::shared_ptr<GLTexture> tex);
	void ShiftTexture(const float dvec[2]);
	void RotateTexture(float angle);
	void ScaleTexture(float ds);
	void ResetTexture();
	int GetSmoothingGroup();
	void SetSmoothingGroup(int);
	bool GetTexVecs(float vecs[2][4]);
	void SetTexVecs(float vecs[2][4]);
	bool GetTexAndAngle(std::shared_ptr<GLTexture>& tex, float& angle);
	void SetTexAngle(float angle);

	cSignal<int> sel_changed_signal;
};





#endif
